# Copyright (c) Mengning Software. 2023. All rights reserved.
#
# Super IDE licensed under GNU Affero General Public License v3 (AGPL-3.0) .
# You can use this software according to the terms and conditions of the AGPL-3.0.
# You may obtain a copy of AGPL-3.0 at:
#
#    https://www.gnu.org/licenses/agpl-3.0.txt
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
# PURPOSE.
# See the AGPL-3.0 for more details.

import logging
import os
import platform
import sys

import click

from installer import __title__, __version__, core, exception, util
from installer.python import check as python_check

log = logging.getLogger(__name__)


@click.group(name="main", invoke_without_command=True)
@click.version_option(__version__, prog_name=__title__)
@click.option("--verbose", is_flag=True, default=False, help="Verbose output")
@click.option("--shutdown-piohome/--no-shutdown-piohome", is_flag=True, default=True)
@click.option("--dev", is_flag=True, default=False)
@click.option(
    "--ignore-python",
    multiple=True,
    help="A path to Python to be ignored (multiple options and unix wildcards are allowed)",
)
@click.option(
    "--pypi-index-url",
    help="Custom base URL of the Python Package Index (default `https://pypi.org/simple`)",
)
@click.pass_context
def cli(
    ctx, verbose, shutdown_piohome, dev, ignore_python, pypi_index_url
):  # pylint:disable=too-many-arguments
    if verbose:
        logging.getLogger("installer").setLevel(logging.DEBUG)
    if pypi_index_url:
        os.environ["PIP_INDEX_URL"] = pypi_index_url
    ctx.obj["dev"] = dev
    if ctx.invoked_subcommand:
        return

    click.echo("Installer version: %s" % __version__)
    click.echo("Platform: %s" % platform.platform(terse=True))
    click.echo("Python version: %s" % sys.version)
    click.echo("Python path: %s" % sys.executable)

    try:
        core.install_platformio_core(shutdown_piohome, dev, ignore_python)
    except exception.PIOInstallerException as exc:
        raise click.ClickException(str(exc))


@cli.group()
def check():
    pass


@check.command()
def python():
    try:
        python_check()
        click.secho(
            "The Python %s (%s) interpreter is compatible."
            % (platform.python_version(), util.get_pythonexe_path()),
            fg="green",
        )
    except (exception.IncompatiblePythonError, exception.PythonVenvModuleNotFound) as e:
        raise click.ClickException(
            "The Python %s (%s) interpreter is not compatible.\nReason: %s"
            % (platform.python_version(), util.get_pythonexe_path(), str(e))
        )


@check.command("core")
@click.option("--auto-upgrade/--no-auto-upgrade", is_flag=True, default=True)
@click.option("--global", is_flag=True, default=False)
@click.option("--version-spec", default=None)
@click.option(
    "--dump-state",
    type=click.Path(
        exists=False, file_okay=True, dir_okay=True, writable=True, resolve_path=True
    ),
)
@click.pass_context
def core_check(ctx, **kwargs):
    try:
        state = core.check(
            develop=ctx.obj.get("dev", False),
            global_=kwargs.get("global"),
            auto_upgrade=kwargs.get("auto_upgrade"),
            version_spec=kwargs.get("version_spec"),
        )
        if kwargs.get("dump_state"):
            core.dump_state(target=str(kwargs.get("dump_state")), state=state)
        click.secho(
            "Found compatible SuperIDE Core %s -> %s"
            % (state.get("core_version"), state.get("si_exe")),
            fg="green",
        )
    except exception.InvalidPlatformIOCore as e:
        raise click.ClickException(
            "Compatible SuperIDE Core not found.\nReason: %s" % str(e)
        )


def main():
    return cli(obj={})  # pylint: disable=no-value-for-parameter, unexpected-keyword-arg


if __name__ == "__main__":
    sys.exit(main())
